﻿using System;
using System.Linq;
using System.Collections.Generic;
using System.Web.UI.WebControls;
using Emporium_Web.Controls;
using Emporium_Web.Enums;
using Emporium_Web.DBML;
using System.Linq.Expressions;

namespace Emporium_Web
{
    public partial class OrdenCorteList : System.Web.UI.Page
    {
        public string SortExpression
        {
            get
            {
                return ViewState["gv_SortExpression"] == null ? "" : ViewState["gv_SortExpression"].ToString();
            }
            set
            {
                ViewState["gv_SortExpression"] = value;
            }
        }

        public string SortDirection
        {
            get
            {
                return ViewState["gv_SortDirection"] == null ? "" : ViewState["gv_SortDirection"].ToString();
            }
            set
            {
                ViewState["gv_SortDirection"] = value;
            }
        }

        private int IdSeleccionado
        {
            get { return (int)ViewState["IdSeleccionado"]; }
            set { }
        }

        /// <summary>
        /// Los componentes.
        /// </summary>
        private List<OrdenCorteContador> OrdenCorteContadorList
        {
            get
            {
                return ViewState["OrdenCorteContadorList"] == null ? null : (List<OrdenCorteContador>)ViewState["OrdenCorteContadorList"];
            }
            set
            {
                ViewState["OrdenCorteContadorList"] = value;
            }
        }

        [Serializable]
        private class OrdenCorteContador
        {
            public int CodigoOrden { get; set; }
            public int TotalPrendas { get; set; }            
        }

        protected void Page_Load(object sender, EventArgs e)
        {
            if (!IsPostBack)
            {
                Master.ActualizaMenu(MenuPrincipal.Produccion, (int)MenuProduccion.OrdenCorte);
                Master.AgregarBreadcrumb("Orden de Corte", "#", true);
                Master.AgregarBreadcrumb("Listado", "#", false);

                warningMessage.Visible = false;
                errorMessage.Visible = false;
                lblMensajeGridFooter.Text = String.Format(Resources.MensajesValidacion.GridFooterMessage, 3);

                OrdenCorteContadorList = new List<OrdenCorteContador>();
                ListarOrdenes();
            }
        }

        protected void btnBuscar_Click(object sender, EventArgs e)
        {
            try
            {
                ListarOrdenes();
            }
            catch (Exception x)
            {
                lblErrorMessage.Text = x.Message;
                errorMessage.Visible = true;
            }
        }

        protected void btnAdicionar_Click(object sender, EventArgs e)
        {
            Response.Redirect("OrdenCorteForm.aspx?Operacion=" + (int)AccionesForm.Adicionar);
        }

        protected void btnModificar_Click(object sender, EventArgs e)
        {
            try
            {
                int codigo = 0;
                if (Int32.TryParse(hdnSeleccion.Value.ToString(), out codigo))
                {
                    Response.Redirect("OrdenCorteForm.aspx?Operacion=" + (int)AccionesForm.Modificar + "&OrdenCorteId=" + codigo);
                }
                else
                {
                    warningMessage.Visible = true;
                    lblWarningMessage.Text = Resources.MensajesValidacion.NoItemSelected;
                }
            }
            catch (Exception x)
            {
                lblErrorMessage.Text = x.Message;
                errorMessage.Visible = true;
            }
        }

        protected void btnEliminar_Click(object sender, EventArgs e)
        {
            try
            {
                int codigo = 0;
                if (Int32.TryParse(hdnSeleccion.Value.ToString(), out codigo))
                {
                    Eliminar();
                    ListarOrdenes();
                }
                else
                {
                    warningMessage.Visible = true;
                    lblWarningMessage.Text = Resources.MensajesValidacion.NoItemSelected;
                }
            }
            catch (Exception x)
            {
                lblErrorMessage.Text = x.Message;
                errorMessage.Visible = true;
            }
        }

        protected void btnFinalizar_Click(object sender, EventArgs e)
        {
            try
            {
                int codigo = 0;
                if (Int32.TryParse(hdnSeleccion.Value.ToString(), out codigo))
                {
                    TablasDataContext database = new TablasDataContext();
                    //Se actualizar el estado a Finalizado
                    PR_OrdenCorte orden = database.PR_OrdenCorte.FirstOrDefault(c => c.OrdCor_Id == codigo);

                    if (orden.OrdCor_Estado == 'F')
                    {
                        warningMessage.Visible = true;
                        lblWarningMessage.Text = "Orden de Corte ya se encuentra Finalizado";
                        return;
                    }
                    else
                    {
                        //Se busca la ruta 1 (Corte)
                        DE_RutaProduccion ruta = database.DE_RutaProduccion.FirstOrDefault(c => c.Estilo_Id == orden.Estilo_Id && c.Ruta_Orden == 1);

                        if (ruta == null)
                        {
                            warningMessage.Visible = true;
                            lblWarningMessage.Text = "No existe ruta de producción con orde 1";
                            return;
                        }

                        Finalizar(orden, ruta, database);
                        ListarOrdenes();
                    }
                }
                else
                {
                    warningMessage.Visible = true;
                    lblWarningMessage.Text = Resources.MensajesValidacion.NoItemSelected;
                    return;
                }
            }
            catch (Exception x)
            {
                lblErrorMessage.Text = x.Message;
                errorMessage.Visible = true;
            }
        }

        protected void btnConsultar_Click(object sender, EventArgs e)
        {
            try
            {
                int codigo = 0;
                if (Int32.TryParse(((LinkButton)sender).Text, out codigo))
                {
                    Response.Redirect("OrdenCorteForm.aspx?Operacion=" + (int)AccionesForm.Consultar + "&OrdenCorteId=" + codigo);
                }
                else
                {
                    warningMessage.Visible = true;
                    lblWarningMessage.Text = Resources.MensajesValidacion.NoItemSelected;
                }
            }
            catch (Exception x)
            {
                lblErrorMessage.Text = x.Message;
                errorMessage.Visible = true;
            }
        }

        private void Eliminar()
        {
            int OrdenCorteId = 0;
            if (Int32.TryParse(hdnSeleccion.Value.ToString(), out OrdenCorteId))
            {
                TablasDataContext database = new TablasDataContext();

                //Se elimina el anterior detalle                               
                //Paquetes
                var detallesPaquete = (from detalle in database.PR_OrdenCortePaquete
                                       where detalle.OrdCor_Id == OrdenCorteId
                                       select detalle);

                foreach (var item in detallesPaquete)
                {
                    database.PR_OrdenCortePaquete.DeleteOnSubmit(item);
                }
                //Distribucion
                var detallesDistribucion = (from detalle in database.PR_OrdenCorteDistribucion
                                            where detalle.OrdCor_Id == OrdenCorteId
                                            select detalle);

                foreach (var item in detallesDistribucion)
                {
                    database.PR_OrdenCorteDistribucion.DeleteOnSubmit(item);
                }
                //
                var detallesProporcion = (from detalle in database.PR_OrdenCorteProporcion
                                          where detalle.OrdCor_Id == OrdenCorteId
                                          select detalle);

                foreach (var item in detallesProporcion)
                {
                    database.PR_OrdenCorteProporcion.DeleteOnSubmit(item);
                }

                //Se elimina la cabecera
                PR_OrdenCorte orden = database.PR_OrdenCorte.FirstOrDefault(c => c.OrdCor_Id == OrdenCorteId);
                database.PR_OrdenCorte.DeleteOnSubmit(orden);

                database.SubmitChanges();
                hdnSeleccion.Value = "";
            }
            else
            {
                warningMessage.Visible = true;
                lblWarningMessage.Text = Resources.MensajesValidacion.NoItemSelected;
            }
        }


        private void Finalizar(PR_OrdenCorte orden, DE_RutaProduccion ruta, TablasDataContext database)
        {
            int OrdenCorteId = 0;
            if (Int32.TryParse(hdnSeleccion.Value.ToString(), out OrdenCorteId))
            {  
                //Se actualizar el estado a Finalizado
                orden.OrdCor_Estado = 'F';

                var listaContTallaPrendas = from detalles in database.PR_OrdenCortePaquete
                                            where detalles.OrdCor_Id == OrdenCorteId 
                                            group detalles by detalles.Talla_Id into g                                            
                                            select new
                                            {
                                                CodigoTalla = g.Key,   
                                                Talla = g.Max(c=> c.OrdCorPaq_Talla),
                                                Prendas = g.Sum(c => c.OrdCorPaq_Prendas)
                                            };

                //Se insertan en la tabla acumulada.
                PR_MovimientoAcumulado acumulado = null;

                var linea = database.TG_Linea.FirstOrDefault(c => c.Actividad_Id == ruta.Actividad_Id && c.Linea_Codigo == "000"); 

                foreach (var item in listaContTallaPrendas)
                {
                    acumulado = new PR_MovimientoAcumulado();
                    acumulado.OrdPro_Id = orden.OrdPro_Id;
                    acumulado.Sector_Id = ruta.Proveedor_Id.Value;
                    acumulado.Sector_Nombre = ruta.TG_Proveedor.Proveedor_Nombre.ToUpper();
                    acumulado.Proceso_Id = ruta.Proceso_Id;
                    acumulado.Proceso_Descripcion = ruta.TG_Actividad.TG_Proceso.Proceso_Descripcion.ToUpper();
                    acumulado.Actividad_Id = ruta.Actividad_Id;
                    acumulado.Actividad_Descripcion = ruta.TG_Actividad.Actividad_Descripcion.ToUpper();                    
                    acumulado.Estilo_Id = orden.Estilo_Id;
                    acumulado.MovAcu_Color = orden.OrdCor_Combinacion.ToUpper();
                    acumulado.MovAcu_Talla = item.Talla;
                    acumulado.Talla_Id = item.CodigoTalla;
                    acumulado.Combinacion_Id = orden.OrdCor_Combinacion_Id;
                    acumulado.MovAcu_Ingreso = Convert.ToInt32(item.Prendas.Value);
                    acumulado.MovAcu_Proceso = 0;
                    acumulado.MovAcu_Merma = 0;

                    if (linea != null)
                    {
                        acumulado.Linea_Id = linea.Linea_Id;
                        acumulado.Linea_Descripcion = linea.Linea_Descripcion;
                    }

                    database.PR_MovimientoAcumulado.InsertOnSubmit(acumulado);
                }

                //Se obtiene ruta destino

                var rutasEstilos = database.DE_RutaProduccion.ToList().FindAll(c => c.Estilo_Id == orden.Estilo_Id);

                var rutasOrigen = rutasEstilos.FindAll(c => c.Proceso_Id == Convert.ToInt32(ruta.Proceso_Id) &&
                                                            c.Actividad_Id == Convert.ToInt32(ruta.Actividad_Id));

                List<DE_RutaProduccion> lstRutasDestino = new List<DE_RutaProduccion>();
                foreach (var item in rutasOrigen)
                {
                    var rutaProd = rutasEstilos.FindAll(c => c.Ruta_Orden == item.Ruta_Orden + 1);
                    if (rutaProd != null)
                        lstRutasDestino.AddRange(rutaProd);
                }

                //Se insertan en la resumen paquetes.
                PR_ResumenPaquetes paquete = null;

                foreach (var item in orden.PR_OrdenCortePaquete)
                {
                    foreach (var rutaDestino in lstRutasDestino)
                    {
                        paquete = new PR_ResumenPaquetes();

                        paquete.OrdPro_Id = orden.OrdPro_Id;
                        paquete.Sector_Ori_Id = ruta.Proveedor_Id.Value;
                        paquete.Sector_Ori_Nombre = ruta.TG_Proveedor.Proveedor_Nombre.ToUpper();
                        paquete.Proceso_Ori_Id = ruta.Proceso_Id;
                        paquete.Proceso_Ori_Descripcion = ruta.TG_Actividad.TG_Proceso.Proceso_Descripcion.ToUpper();
                        paquete.Actividad_Ori_Id = ruta.Actividad_Id;
                        paquete.Actividad_Ori_Descripcion = ruta.TG_Actividad.Actividad_Descripcion.ToUpper();
                        paquete.OrdCor_Id = item.OrdCor_Id;
                        paquete.OrdCorPaq_Numero = item.OrdCorPaq_Numero;
                        
                        paquete.Proceso_Des_Id = rutaDestino.Proceso_Id;
                        paquete.Proceso_Des_Descripcion = rutaDestino.TG_Actividad.TG_Proceso.Proceso_Descripcion.ToUpper();
                        paquete.Actividad_Des_Id = rutaDestino.Actividad_Id;
                        paquete.Actividad_Des_Descripcion = rutaDestino.TG_Actividad.Actividad_Descripcion.ToUpper();

                        if (linea != null)
                        {
                            paquete.Linea_Ori_Id = linea.Linea_Id;
                            paquete.Linea_Ori_Descripcion = linea.Linea_Descripcion;
                        }

                        var lineaDestino = database.TG_Linea.FirstOrDefault(c => c.Actividad_Id == rutaDestino.Actividad_Id && c.Linea_Codigo == "000");
                        if (lineaDestino != null)
                        {
                            paquete.Linea_Des_Id = lineaDestino.Linea_Id;
                            paquete.Linea_Des_Descripcion = lineaDestino.Linea_Descripcion;
                        }

                        database.PR_ResumenPaquetes.InsertOnSubmit(paquete);
                    }                   
                }

                database.SubmitChanges();
                hdnSeleccion.Value = "";
            }
            else
            {
                warningMessage.Visible = true;
                lblWarningMessage.Text = Resources.MensajesValidacion.NoItemSelected;
            }
        }

        protected void gvPagerPageChanged(object sender, DataNavigatorEventArgs e)
        {
            ListarOrdenes();
        }

        private void ListarOrdenes()
        {
            TablasDataContext database = new TablasDataContext();

            int codigo = txtOrdenCorte.Text == string.Empty ? 0 : Convert.ToInt32(txtOrdenCorte.Text);
            int ordenProduccion = txtOrdenProduccion.Text == string.Empty ? 0 : Convert.ToInt32(txtOrdenProduccion.Text);            
            int codigoEstilo = txtCodigoEstilo.Text == string.Empty ? 0 : Convert.ToInt32(txtCodigoEstilo.Text);

            var listarQuery = from Ordenes in database.PR_OrdenCorte
                              where (Ordenes.OrdCor_Id == codigo || codigo == 0)
                                    && (Ordenes.OrdPro_Id == ordenProduccion || ordenProduccion == 0)
                                    && (Ordenes.Estilo_Id == codigoEstilo || codigoEstilo == 0)                                    
                              select Ordenes;

            var listaContadores = from detalles in database.PR_OrdenCortePaquete
                                  group detalles by detalles.OrdCor_Id into g
                                  select new
                                  {
                                      CodigoPedido = g.Key,                                      
                                      PrendasSolicitadas = g.Sum(c => c.OrdCorPaq_Prendas)
                                  };

            foreach (var item in listaContadores)
            {
                OrdenCorteContadorList.Add(new OrdenCorteContador()
                {
                    CodigoOrden = item.CodigoPedido,
                    TotalPrendas = Convert.ToInt32(item.PrendasSolicitadas)
                });
            }

            listarQuery = OrdenarQuery(listarQuery);

            var listarQuery1 = listarQuery.Skip((gvPager.CurrentPage - 1) * gvPager.PageSize).Take(gvPager.PageSize).ToList();

            gvOrdenesCorte.DataSource = listarQuery1;
            gvOrdenesCorte.DataBind();

            int totalReg = listarQuery.Count();

            if (totalReg > 0)
            {
                gvOrdenesCorte.UseAccessibleHeader = false;
                gvOrdenesCorte.HeaderRow.TableSection = TableRowSection.TableHeader;
                gvPager.Visible = true;
                gvPager.TotalRowCount = totalReg;
                warningMessage.Visible = false;
            }
            else
            {
                lblWarningMessage.Text = Resources.MensajesValidacion.NoDataFound;
                warningMessage.Visible = true;
                gvPager.Visible = false;
            }

            lblMensajeGridFooter.Text = String.Format(Resources.MensajesValidacion.GridFooterMessage, totalReg);
            ActivaIconoOrdenamiento();
        }

        private void ActivaIconoOrdenamiento()
        {
            if (gvOrdenesCorte.HeaderRow == null)
            {
                return;
            }

            LinkButton lnkSender = null;
            LinkButton lnkSortDown = null;
            LinkButton lnkSortUp = null;

            if (this.SortDirection != null && this.SortDirection.ToUpper().Equals("ASC"))
            {
                lnkSender = (LinkButton)gvOrdenesCorte.HeaderRow.FindControl("lnkSortUp" + this.SortExpression);
                if (lnkSender != null)
                    lnkSortDown = (LinkButton)gvOrdenesCorte.HeaderRow.FindControl(lnkSender.ID.Replace("SortUp", "SortDown"));
                if (lnkSortUp != null) lnkSortDown.CssClass = "sort-down";
                if (lnkSender != null) lnkSender.CssClass = "sort-up active";
            }
            else
            {
                lnkSender = (LinkButton)gvOrdenesCorte.HeaderRow.FindControl("lnkSortDown" + this.SortExpression);
                if (lnkSender != null)
                    lnkSortUp = (LinkButton)gvOrdenesCorte.HeaderRow.FindControl(lnkSender.ID.Replace("SortDown", "SortUp"));

                if (lnkSortUp != null) lnkSortUp.CssClass = "sort-up";
                if (lnkSender != null) lnkSender.CssClass = "sort-down active";
            }
        }

        protected void gvOrdenesCorte_RowDataBound(object sender, GridViewRowEventArgs e)
        {
            if (e.Row.RowType == DataControlRowType.DataRow)
            {
                var orden = (PR_OrdenCorte)(e.Row.DataItem);

                Label lblEstado = (Label)e.Row.FindControl("lblEstado");
                if (lblEstado != null && lblEstado.Text != string.Empty)
                {
                    lblEstado.Text = lblEstado.Text == "R" ? "REGISTRADO" : "FINALIZADO";
                }

                if (OrdenCorteContadorList.Count > 0 && OrdenCorteContadorList.Find(c => c.CodigoOrden == orden.OrdCor_Id) != null)
                {
                    Label lblTotasPrendas = (Label)e.Row.FindControl("lblTotasPrendas");
                    if (lblTotasPrendas != null && lblTotasPrendas.Text == string.Empty)
                    {
                        lblTotasPrendas.Text = OrdenCorteContadorList.Find(c => c.CodigoOrden == orden.OrdCor_Id).TotalPrendas.ToString();
                    }
                }
            }            
        }


        private IQueryable<PR_OrdenCorte> OrdenarQuery(IQueryable<PR_OrdenCorte> listarQuery)
        {
            if (this.SortExpression == null || this.SortExpression.Trim().Equals(""))
            {
                this.SortExpression = "OrdenCorte";
            }

            if (this.SortDirection == null || this.SortDirection.Trim().Equals(""))
            {
                this.SortDirection = "DES";
            }

            if (this.SortExpression == "OrdenCorte")
            {
                if (this.SortDirection.ToUpper().Equals("ASC"))
                {
                    listarQuery = listarQuery.OrderBy(c => c.OrdCor_Id);
                }
                else
                {
                    listarQuery = listarQuery.OrderByDescending(c => c.OrdCor_Id);
                }
            }
            else if (this.SortExpression == "OrdenProduccion")
            {
                if (this.SortDirection.ToUpper().Equals("ASC"))
                {
                    listarQuery = listarQuery.OrderBy(c => c.OrdPro_Id);
                }
                else
                {
                    listarQuery = listarQuery.OrderByDescending(c => c.OrdPro_Id);
                }
            }
            else if (this.SortExpression == "Referencia")
            {
                if (this.SortDirection.ToUpper().Equals("ASC"))
                {
                    listarQuery = listarQuery.OrderBy(c => c.OrdCor_Referencia);
                }
                else
                {
                    listarQuery = listarQuery.OrderByDescending(c => c.OrdCor_Referencia);
                }
            }
            else if (this.SortExpression == "Tela")
            {
                if (this.SortDirection.ToUpper().Equals("ASC"))
                {
                    listarQuery = listarQuery.OrderBy(c => c.OrdCor_Tela);
                }
                else
                {
                    listarQuery = listarQuery.OrderByDescending(c => c.OrdCor_Tela);
                }
            }
            else if (this.SortExpression == "Etiqueta")
            {
                if (this.SortDirection.ToUpper().Equals("ASC"))
                {
                    listarQuery = listarQuery.OrderBy(c => c.OrdCor_Combinacion);
                }
                else
                {
                    listarQuery = listarQuery.OrderByDescending(c => c.OrdCor_Combinacion);
                }
            }
            else if (this.SortExpression == "Color")
            {
                if (this.SortDirection.ToUpper().Equals("ASC"))
                {
                    listarQuery = listarQuery.OrderBy(c => c.OrdCor_Color);
                }
                else
                {
                    listarQuery = listarQuery.OrderByDescending(c => c.OrdCor_Color);
                }
            }              


            return listarQuery;
        }

        protected void gvOrdenesCorte_RowCommand(object sender, GridViewCommandEventArgs e)
        {
            try
            {
                if (gvOrdenesCorte.HeaderRow == null)
                {
                    return;
                }

                this.SortExpression = e.CommandArgument != null ? e.CommandArgument.ToString() : "Id";
                this.SortDirection = e.CommandName.Equals("SortUp") ? "ASC" : "DES";

                ListarOrdenes();

            }
            catch (Exception x)
            {
                lblErrorMessage.Text = x.Message;
                errorMessage.Visible = true;
            }
        }

        protected void btnBuscarEstilo_Click(object sender, EventArgs e)
        {
            estiloAdd.ListarEstilos();
        }

        protected void estiloAdd_Seleccionado(object sender, EventArgs e)
        {
            txtCodigoEstilo.Text = estiloAdd.CodigoSeleccionado.ToString();
        }       
    }
}